﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SklepISI.Core.Interfaces;
using SklepISI.Core.Models;
using AutoMapper;

namespace SklepISI.Core.Services
{
    public class OrderService : IOrderService
    {
        public OrderModel CreateOrder(NewOrderModel order)
        {
            if (order == null || order.Products == null || order.DeliveryAddress == null)
                throw new ArgumentNullException();

            Order newOrder = new Order()
                                 {
                                     DeliveryAddress = order.DeliveryAddress,
                                     OrderStatusID = 1,
                                     UserID = order.UserId,
                                     OrderContents = order.Products.Select(p => new OrderContent()
                                                                                     {
                                                                                         Quantity = p.Quantity,
                                                                                         ProductID = p.Product.ProductId,
                                                                                         Price = p.Product.Price
                                                                                     }).ToList()
                                 };
            
            using (var ctx = new Entities())
            {
                ctx.Orders.Add(newOrder);
                ctx.SaveChanges();
                newOrder = ctx.Orders.Include("OrderStatus").FirstOrDefault(o => o.ID == newOrder.ID);
                return Mapper.Map<Order, OrderModel>(newOrder);
               
            }
        }

        public OrderModel UpdateOrder(OrderModel order)
        {
            var toReturn = order;
            if (order == null) throw new ArgumentNullException();
            if (order.Id == 0)
                throw new ArgumentException("Id must be set");

            var _order = new Order();

            using (var ctx = new Entities())
            {
                _order = ctx.Orders.Find(order.Id);
                _order.OrderStatusID = order.Status.ID;
                ctx.SaveChanges();
                toReturn = Mapper.Map<Order, OrderModel>(_order);
            }
            return toReturn;
        }

        public bool RemoveOrder(int orderId)
        {
            using (var ctx = new Entities())
            {
                var dbOrder = ctx.Orders.FirstOrDefault(o => o.ID == orderId);
                if (dbOrder == null)
                {
                    throw new ObjectNotFoundException();
                }
                else
                {
                    ctx.Orders.Remove(dbOrder);
                    return true;
                }
            }
        }

        public IEnumerable<OrderContentModel> GetOrderProducts(int orderId)
        {
            using(var ctx = new Entities())
            {
                var cnt = ctx.OrderContents.Where(c => c.OrderID == orderId).ToList();
                return Mapper.Map<IList<OrderContent>, IList<OrderContentModel>>(cnt);
            }
        }

        public OrderStatusModel GetOrderStatus(int orderId)
        {
            using(var ctx = new Entities())
            {
                var dbStatus = ctx.Orders.FirstOrDefault(o => o.ID == orderId);
                if (dbStatus == null)
                    return null;

                return Mapper.Map<OrderStatus, OrderStatusModel>(dbStatus.OrderStatus);
            }
        }


        public OrderModel GetOrder(int orderId)
        {
            OrderModel orderModel = null;
            using (var ctx = new Entities())
            {
                var dbOrder = ctx.Orders.Include("OrderContents.Product").FirstOrDefault(o => o.ID == orderId);
                if (dbOrder != null)
                {
                    return Mapper.Map<Order, OrderModel>(dbOrder);
                }
            }

            return orderModel;
        }

        public IList<OrderModel> GetUserOrders(int userId)
        {
            using (var ctx = new Entities())
            {
                var dbOrder = ctx.Orders.Include("OrderContents.Product").Where(o => o.UserID == userId).ToList();
                return Mapper.Map<IList<Order>, IList<OrderModel>>(dbOrder);
            }
        }

        public IList<OrderModel> GetOrders()
        {
            using (var ctx = new Entities())
            {
                var dbOrder = ctx.Orders.Include("OrderContents.Product").OrderBy(x=>x.ID).ToList();
                return Mapper.Map<IList<Order>, IList<OrderModel>>(dbOrder);
            }
        }

        public IList<OrderStatusModel> GetOrderStatuses()
        {
            using (var ctx = new Entities())
            {
                var dbOrder = ctx.OrderStatuses.ToList();
                return Mapper.Map<IList<OrderStatus>, IList<OrderStatusModel>>(dbOrder);
            }
        }

        public OrderStatusModel GetStatus(int statusId)
        {
            using (var ctx = new Entities())
            {
                var dbStatus = ctx.OrderStatuses.Where(x => x.ID == statusId).FirstOrDefault();
              

                return Mapper.Map<OrderStatus, OrderStatusModel>(dbStatus);
            }
        }
    }
}
